CaptureForm Expression Builder
The Expression Builder allows you to manipulate variable values similar to CaptureForm SQL queries, but without the need for a database source. Here you can you specify the value by calculating an expression. You can define the properties of a CaptureForm expression using the fields below.
Expression Name
This is the name of the expression as it appears in the Process Tree. The expression name isn't used by FormFusion, but lets you create a descriptive name for the expression (such as "Get email address" or "Get vendor email address").
When should this expression execute?
This dropdown controls when the expression will execute.
- Pre - Executes before any data has been processed on the server side.
- Page - Executes before each page is processed. Note: Most expressions will be Page expressions.
- Post - Executes after the entire job is complete.
- Test - Prevents the expression from executing on the server.
Store results to variable
This dropdown contains a list of variables available from within variable storage. The variable selected will store the result of the expression defined within this CaptureForm Expression.
This expression should be used during sort (see help for more information)
To facilitate the sorting process you must specify which expression should be executed during the sort. This decreases program latency by only executing the expressions that you instruct FormFusion to execute. Sorting is performed before the processing of the report file is begun.
Terminate processing of the template if this query returns an error
Checking this checkbox will force FormFusion to terminate the current process being executed if an error occurs in this expression. If you want processing to continue regardless if there is an error in this expression, then leave this unchecked.
Type your expression:
This box is where you enter the expression that defines the actions for this CaptureForm expression.
Functions
Any function specified in this list may be used as part of the CaptureForm expression. Functions can be double-clicked or dragged to be placed in the Type your expression field. A description of each function can be viewed below the Functions list, including function parameter types and return types. For a list of functions, see: CaptureForm Expression Functions.
Test Expression
The Test Expression button (green triangle) allows you to test the expression you created without committing the results. After testing the expression you can save the results as sample data for preview within FormStamp.
Expression Language
There are no statements, no assignment, no semicolons, no local variables and no loops. The expression is parsed, evaluated once, and the result is stored into the Expression node's target variable. Anything after the end of the expression is labeled as Unexpected character.
:Name Reads a Variable
The colon prefix is required. A bare Name is treated as a function call and fails with Undefined identifier. Dots are permitted inside the name (:Group.Field). Variable names are matched case-sensitively — :StudentID and :StudentId are not the same variable, and the wrong one gives Invalid variable name.
Avoid Using {Name}
The grammar has a field-reference form, but neither the nFusion runtime nor the Developer expression editor registers a field resolver for Capture Forms. It always fails with Invalid field name "...". Treat { } as unavailable.
Strings Use Single or Double Quotes
Both single and double quotes work and neither terminates the other. A string literal that spans a line break has the break replaced with a space.
Using Numbers
Integers are 64-bit; reals accept a leading . (.5) and exponent notation (1.2e-3). There are no hex, currency or thousands-separator literals.
Booleans and Boolean Operators
The reserved-word table is empty, so there are no true/false literals and no AND, OR or NOT. Booleans only ever arrive from a comparison or from IsNull. Compose them by nesting If.
Example: A and B
If(a, If(b, yes, no), no)
Example: A or B
If(a, yes, If(b, yes, no))
Comparisons Do Not Chain
Exactly one comparison operator is allowed at the top level of an expression. 1 < 2 < 3 is a syntax error, not a bug in your logic. Parenthesise and nest If instead.
| Level | Operators | Behavior |
|---|---|---|
| 1 | ( ) | Grouping. Also the function-call form. Every function requires parentheses, including Now(). |
| 2 | +x -x | Unary sign. Implemented as 0 - x, so unary minus on a string errors. |
| 3 | * / | Numeric only. Null or string operand is an error. |
| 4 | + - | + is add or concatenate depending on operand types; - is numeric or date only. |
| 5 | = <> < > <= >= | Returns Boolean. Not chainable. Null operand is an error, not false. <> is the inequality operator — there is no !=. |
Type Behavior
Dates
Date + number and Date - number shift by days; Date - Date gives the difference. Functions declaring a Date parameter will accept a string and parse it using the server's locale, so an ambiguous format is a portability risk.
The + Operator Concatenates Whenever Either Side is a String
It checks the operand's type, not whether its contents look numeric. A String variable holding "100" plus 5 produces "1005", not 105. There is no cast function in the language, so the only fix is to declare the variable as Integer or Float in the print parameter.
The / Between Two Integers is Integer Division
7 / 2 is 3. Force a real by making one side real: 7 / 2.0 is 3.5. Division by zero logs Divide by zero and aborts.
String Comparison is Case-Insensitive and Numerically Aware
If either operand is a string, both are compared with the Windows natural-sort comparison. So "abc" = "ABC" is true, and "A2" < "A10" is true — the opposite of plain lexical ordering. Do not rely on this for case-sensitive matching; there is no case-sensitive comparison available.
Passing Null to a Typed Parameter Error
Every parameter except If's branches and IsNull's argument is declared with a concrete type and checked before the call, producing Parameter 1 (string) expected String but found null value. Guard with If(IsNull(...), ...) or neutralize with + "".
Only the Taken Branch is Evaluated
Its two result parameters are untyped, so they are never touched by the type check, and only the selected one is computed. That is what makes guarding safe: in If(IsNull(:x), "n/a", SubString(:x, 1, 3)) the SubString genuinely does not run when :x is null.
Debugging
Turn on the CaptureForm Debug Log
It prints Executing expression: <name>, then the target Variable: and the full Expression: text as evaluated. Queries log each returned record with the column-to-variable mapping, which is the fastest way to confirm whether a variable was populated at all.
Add a Throwaway Probe Expression
Write to a scratch String variable and read it off the output. This distinguishes null from empty from whitespace in one shot — the brackets make trailing spaces visible, and it cannot itself fail on a null:
If(IsNull(:Target), "<NULL>", "[" + :Target + "]")
Execution Order
Capture Form children run grouped by their Applied stage — Pre, then Page, then Post — and within a stage by their configured Order. An Expression only sees what earlier nodes have already put in the variables, and each Expression clears its own target before it evaluates. An expression reading a variable that a later query populates reads null, every time.